package custom;

import com.alibaba.fastjson.JSON;
import entity.MessageData;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Objects;

/**
 * @author:Eric
 * @date:2021/8/4 10:34
 * <p>
 * +---------------------------------------------------------------+
 * | 魔数 2byte | 协议版本号 1byte | 序列化算法 1byte | 报文类型 1byte  |
 * +---------------------------------------------------------------+
 * | 状态 1byte |        保留字段 4byte     |      数据长度 4byte     | 
 * +---------------------------------------------------------------+
 * |                   数据内容 （长度不定）                          |
 * +---------------------------------------------------------------+
 */
@Slf4j
public class CustomDecoder extends ByteToMessageDecoder {

    private static final int BASE_LENGTH = 14;

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        log.info("数据解码……");
        if (in.readableBytes() < BASE_LENGTH) {
            return;
        }
        //标记当前读指针
        in.markReaderIndex();
        //跳过魔数
//        in.skipBytes(2);
        char c = in.readChar();
        //获取协议版本号
        byte version = in.readByte();
        //获取序列化算法
        byte serializeType = in.readByte();
        //获取报文类型
        byte msgType = in.readByte();
        //获取状态
        byte state = in.readByte();
        //跳过保留字段
//        in.skipBytes(4);
        int i = in.readInt();
        //获取数据长度
        int dataLength = in.readInt();
        //当前指针移动到数据头部
        if (in.readableBytes() < dataLength) {
            //数据不全
            in.resetReaderIndex();
            return;
        }
        byte[] bytes = new byte[dataLength];
        //数据读取到bytes中
        in.readBytes(bytes);
        MessageData messageData = JSON.parseObject(bytes, MessageData.class);
        if (Objects.nonNull(messageData)) {
            out.add(messageData);
        }
        log.info("魔数：{}，保留字段：{}", c, i);
        log.info("解码结果->版本号：{}，序列化算法：{}，报文类型：{}，状态：{}", version, serializeType, msgType, state);
    }
}
